到目前為止我的程式大多只能輸入輸出在「螢幕」上,但現實應用中常常需要存下程式運算的結果(例如紀錄日誌、存成文字檔)、從檔案中讀取資料(例如 CSV、文字檔、設定檔)。所以檔案 I/O(Input/Output)就是程式能夠與外部世界互動的關鍵!
f = open("data.txt", "r") # 開啟檔案
# ...操作...
f.close() # 關閉檔案
模式 (mode) 說明:
1) "r" 讀取(檔案必須存在)
with open("data.txt", "r", encoding="utf-8") as f:
print(f.read())
2) "w" 覆蓋寫入(會清空舊檔)
with open("out.txt", "w", encoding="utf-8") as f:
f.write("重新開始寫入\n")
3) "a" 追加寫入(不清空)
with open("log.txt", "a", encoding="utf-8") as f:
f.write("追加一行\n")
甚麼是seek
在 Python 中,檔案物件(file object)有一個「檔案指標」(file pointer),它決定了你下一次讀或寫的位置。
seek(offset, whence=0) 就是用來移動檔案指標的方法。
4) "x" 僅新建(已存在就報錯)
try:
with open("unique.txt", "x", encoding="utf-8") as f:
f.write("只在不存在時建立\n")
except FileExistsError:
print("檔案已存在,安全取消!")
5) "r+" 讀寫(不清空,指標在檔頭)
with open("doc.txt", "r+", encoding="utf-8") as f:
old = f.read()
f.seek(0)
f.write("前綴\n" + old)
6) "w+" 清空後讀寫
with open("doc.txt", "w+", encoding="utf-8") as f:
f.write("新內容\n")
f.seek(0)
print(f.read()) # 可讀,但舊內容已清空
7) "a+" 讀寫(不清空,寫入在尾端)
with open("doc.txt", "a+", encoding="utf-8") as f:
f.write("尾端追加\n")
f.seek(0)
print(f.read())
手動 open() / close() 很容易忘記關閉檔案,造成檔案被鎖住。
所以 Python 提供了 with open 語法:
with open("data.txt", "r") as f:
content = f.read()
print(content) # 自動關閉檔案
with 區塊結束後,檔案會自動關閉,不用再寫 f.close()。
with open("data.txt", "r") as f:
print("read():")
print(f.read()) # 讀取整個檔案內容
with open("data.txt", "r") as f:
print("readline():")
print(f.readline()) # 讀取一行
with open("data.txt", "r") as f:
print("readlines():")
print(f.readlines()) # 讀取所有行,回傳 list
# 覆蓋寫入
with open("output.txt", "w") as f:
f.write("Hello, file!\n")
# 追加模式
with open("output.txt", "a") as f:
f.write("Add another line!\n")
執行後,output.txt 的內容會隨著模式不同而更新。
import datetime
log = f"{datetime.datetime.now()}: 程式執行成功\n"
with open("log.txt", "a", encoding="utf-8") as f:
f.write(log)
print("日誌已更新!")
每次執行,log.txt 會新增一行記錄。
常用參數補充:
from pathlib import Path
p = Path("data") / "out.txt"
with p.open("a", encoding="utf-8") as f:
f.write("hi\n")
筆記
try:
with open("maybe.txt", "r", encoding="utf-8") as f:
data = f.read()
except FileNotFoundError:
data = "" # 或者給提示訊息
今天學了 檔案的讀寫操作,能讓程式「留下痕跡」,不再只是輸出到螢幕。我覺得有點複雜!
明天要學習模組化專案結構,包括如何將程式拆成多個檔案、如何匯入自訂模組,開始體驗「專案架構」的規劃!